package com.legsem.jhosync.model;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import org.apache.commons.dbutils.ResultSetHandler;

public class ClientDoc extends Model implements ResultSetHandler < ClientDoc > {

    private static final long serialVersionUID = 1L;

    public static final String TABLE_NAME = "CLIENTDOCS";

    public static final String SQL_CREATE = "CREATE TABLE "
            + TABLE_NAME
            + " (\n"
            + "         CLIENT_ID         VARCHAR (255),\n"
            + "         APP_NAME          VARCHAR (255),\n"
            + "         SOURCE_NAME       VARCHAR (255),\n"
            + "         USER_LOGIN        VARCHAR (255),\n"
            + "         CD                CLOB,\n"
            + "         CD_SIZE           INTEGER,\n"
            + "         PAGE              CLOB,\n"
            + "         DELETE_PAGE       CLOB,\n"
            + "         TOTAL_COUNT_PAGE  INTEGER,\n"
            + "         PAGE_TOKEN        VARCHAR (255),\n"
            + "         CREATE_LINKS      CLOB,\n"
            + "         CREATE_DELETES    CLOB,\n"
            + "         CREATE_ERRORS     CLOB,\n"
            + "         DELETE_ERRORS     CLOB,\n"
            + "         UPDATE_ERRORS     CLOB,\n"
            + "         METADATA_PAGE     CLOB,\n"
            + "         METADATA_SHA1     CHAR(40),\n"
            + "         PRIMARY KEY ( CLIENT_ID, APP_NAME, SOURCE_NAME, USER_LOGIN ),\n"
            + "         FOREIGN KEY ( CLIENT_ID ) REFERENCES CLIENTS ( ID ) ON DELETE CASCADE,\n"
            + "         FOREIGN KEY ( USER_LOGIN ) REFERENCES USERS ( LOGIN ) ON DELETE CASCADE);\n";

    public static final String SQL_DROP = "DROP TABLE " + TABLE_NAME + ";\n";

    private String clientId;
    private String appName;
    private String sourceName;
    private String userLogin;
    private String cd;
    private int cdSize;
    private String page;
    private String deletePage;
    private int totalCountPage;
    private String pageToken;
    private String createLinks;
    private String createDeletes;
    private String createErrors;
    private String deleteErrors;
    private String updateErrors;
    private String metadataPage;
    private String metadataSha1;

    public ClientDoc() {
    }

    public ClientDoc(String clientId, String appName, String sourceName,
            String userLogin) {
        this.clientId = clientId;
        this.appName = appName;
        this.sourceName = sourceName;
        this.userLogin = userLogin;
    }

    public static String getSqlCreate() {
        return SQL_CREATE;
    }

    public static String getSqlDrop() {
        return SQL_DROP;
    }

    public static ClientDoc find(String clientId, String appName,
            String sourceName, String userLogin) throws SQLException {
        return find(clientId, appName, sourceName, userLogin, false);
    }

    public static ClientDoc findForUpdate(String clientId, String appName,
            String sourceName, String userLogin) throws SQLException {
        return find(clientId, appName, sourceName, userLogin, true);
    }

    public static ClientDoc find(String clientId, String appName,
            String sourceName, String userLogin, boolean forUpdate)
            throws SQLException {
        return run
                .query(getConnection(),
                        "SELECT * FROM "
                                + TABLE_NAME
                                + " WHERE CLIENT_ID=? AND APP_NAME=? AND SOURCE_NAME=? AND USER_LOGIN=?"
                                + ((forUpdate) ? " FOR UPDATE" : ""),
                        new ClientDoc(), clientId, appName, sourceName,
                        userLogin);
    }

    public int create() throws SQLException {
        return run
                .update(getConnection(),
                        "INSERT INTO "
                                + TABLE_NAME
                                + ""
                                + " VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
                        clientId, appName, sourceName, userLogin, cd, cdSize,
                        page, deletePage, totalCountPage, pageToken,
                        createLinks, createDeletes, createErrors, deleteErrors,
                        updateErrors, metadataPage, metadataSha1);
    }

    public int delete() throws SQLException {
        return run
                .update(getConnection(),
                        "DELETE FROM "
                                + TABLE_NAME
                                + " WHERE CLIENT_ID=? AND APP_NAME=? AND SOURCE_NAME=? AND USER_LOGIN=?",
                        clientId, appName, sourceName, userLogin);
    }

    public int update() throws SQLException {
        return run
                .update(getConnection(),
                        "UPDATE "
                                + TABLE_NAME
                                + " SET"
                                + " CD = ?,"
                                + " CD_SIZE = ?,"
                                + " PAGE = ?,"
                                + " DELETE_PAGE = ?,"
                                + " TOTAL_COUNT_PAGE = ?,"
                                + " PAGE_TOKEN = ?,"
                                + " CREATE_LINKS = ?,"
                                + " CREATE_DELETES = ?,"
                                + " CREATE_ERRORS = ?,"
                                + " DELETE_ERRORS = ?,"
                                + " UPDATE_ERRORS = ?,"
                                + " METADATA_PAGE = ?,"
                                + " METADATA_SHA1 = ?"
                                + " WHERE  CLIENT_ID=? AND APP_NAME=? AND SOURCE_NAME=? AND USER_LOGIN=?",
                        cd, cdSize, page, deletePage, totalCountPage,
                        pageToken, createLinks, createDeletes, createErrors,
                        deleteErrors, updateErrors, metadataPage, metadataSha1,
                        clientId, appName, sourceName, userLogin);
    }

    public String getClientId() {
        return clientId;
    }

    public void setClientId(String clientId) {
        this.clientId = clientId;
    }

    public String getAppName() {
        return appName;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public String getSourceName() {
        return sourceName;
    }

    public void setSourceName(String sourceName) {
        this.sourceName = sourceName;
    }

    public String getUserLogin() {
        return userLogin;
    }

    public void setUserLogin(String userLogin) {
        this.userLogin = userLogin;
    }

    public String getCd() {
        return cd;
    }

    public void setCd(String cd) {
        this.cd = cd;
    }

    public int getCdSize() {
        return cdSize;
    }

    public void setCdSize(int cdSize) {
        this.cdSize = cdSize;
    }

    public String getPage() {
        return page;
    }

    public void setPage(String page) {
        this.page = page;
    }

    public String getDeletePage() {
        return deletePage;
    }

    public void setDeletePage(String deletePage) {
        this.deletePage = deletePage;
    }

    public int getTotalCountPage() {
        return totalCountPage;
    }

    public void setTotalCountPage(int totalCountPage) {
        this.totalCountPage = totalCountPage;
    }

    public String getPageToken() {
        return pageToken;
    }

    public void setPageToken(String pageToken) {
        this.pageToken = pageToken;
    }

    public String getCreateLinks() {
        return createLinks;
    }

    public void setCreateLinks(String createLinks) {
        this.createLinks = createLinks;
    }

    public String getCreateDeletes() {
        return createDeletes;
    }

    public void setCreateDeletes(String createDeletes) {
        this.createDeletes = createDeletes;
    }

    public String getCreateErrors() {
        return createErrors;
    }

    public void setCreateErrors(String createErrors) {
        this.createErrors = createErrors;
    }

    public String getDeleteErrors() {
        return deleteErrors;
    }

    public void setDeleteErrors(String deleteErrors) {
        this.deleteErrors = deleteErrors;
    }

    public String getUpdateErrors() {
        return updateErrors;
    }

    public void setUpdateErrors(String updateErrors) {
        this.updateErrors = updateErrors;
    }

    public String getMetadataPage() {
        return metadataPage;
    }

    public void setMetadataPage(String metadataPage) {
        this.metadataPage = metadataPage;
    }

    public String getMetadataSha1() {
        return metadataSha1;
    }

    public void setMetadataSha1(String metadataSha1) {
        this.metadataSha1 = metadataSha1;
    }

    public ClientDoc handle(ResultSet rs) throws SQLException {
        if (!rs.next()) {
            return null;
        }
        ClientDoc clientDoc = new ClientDoc();
        ResultSetMetaData meta = rs.getMetaData();
        int cols = meta.getColumnCount();

        for (int i = 0; i < cols; i++) {
            switch (i) {
            case 0:
                clientDoc.setClientId(rs.getString(i + 1));
                break;
            case 1:
                clientDoc.setAppName(rs.getString(i + 1));
                break;
            case 2:
                clientDoc.setSourceName(rs.getString(i + 1));
                break;
            case 3:
                clientDoc.setUserLogin(rs.getString(i + 1));
                break;
            case 4:
                clientDoc.setCd(rs.getString(i + 1));
                break;
            case 5:
                clientDoc.setCdSize(rs.getInt(i + 1));
                break;
            case 6:
                clientDoc.setPage(rs.getString(i + 1));
                break;
            case 7:
                clientDoc.setDeletePage(rs.getString(i + 1));
                break;
            case 8:
                clientDoc.setTotalCountPage(rs.getInt(i + 1));
                break;
            case 9:
                clientDoc.setPageToken(rs.getString(i + 1));
                break;
            case 10:
                clientDoc.setCreateLinks(rs.getString(i + 1));
                break;
            case 11:
                clientDoc.setCreateDeletes(rs.getString(i + 1));
                break;
            case 12:
                clientDoc.setCreateErrors(rs.getString(i + 1));
                break;
            case 13:
                clientDoc.setDeleteErrors(rs.getString(i + 1));
                break;
            case 14:
                clientDoc.setUpdateErrors(rs.getString(i + 1));
                break;
            case 15:
                clientDoc.setMetadataPage(rs.getString(i + 1));
                break;
            case 16:
                clientDoc.setMetadataSha1(rs.getString(i + 1));
                break;
            }
        }

        return clientDoc;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((appName == null) ? 0 : appName.hashCode());
        result = prime * result
                + ((clientId == null) ? 0 : clientId.hashCode());
        result = prime * result
                + ((sourceName == null) ? 0 : sourceName.hashCode());
        result = prime * result
                + ((userLogin == null) ? 0 : userLogin.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        ClientDoc other = (ClientDoc) obj;
        if (appName == null) {
            if (other.appName != null) {
                return false;
            }
        } else if (!appName.equals(other.appName)) {
            return false;
        }
        if (clientId == null) {
            if (other.clientId != null) {
                return false;
            }
        } else if (!clientId.equals(other.clientId)) {
            return false;
        }
        if (sourceName == null) {
            if (other.sourceName != null) {
                return false;
            }
        } else if (!sourceName.equals(other.sourceName)) {
            return false;
        }
        if (userLogin == null) {
            if (other.userLogin != null) {
                return false;
            }
        } else if (!userLogin.equals(other.userLogin)) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "ClientDoc [clientId=" + clientId + ", appName=" + appName
                + ", sourceName=" + sourceName + ", userLogin=" + userLogin
                + ", cd=" + toShortString(cd) + ", cdSize=" + cdSize
                + ", page=" + toShortString(page) + ", deletePage="
                + deletePage + ", totalCountPage=" + totalCountPage
                + ", pageToken=" + pageToken + ", createLinks=" + createLinks
                + ", createDeletes=" + createDeletes + ", createErrors="
                + createErrors + ", deleteErrors=" + deleteErrors
                + ", updateErrors=" + updateErrors + ", metadataPage="
                + metadataPage + ", metadataSha1=" + metadataSha1 + "]";
    }

}
